package com.ce.server.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ce.server.common.RespBean;
import com.ce.server.common.RespPageBean;
import com.ce.server.mapper.*;
import com.ce.server.pojo.*;
import com.ce.server.service.ICheckinService;
import com.ce.server.util.AdminUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 郑爽
 * @since 2021-11-17
 */
@Service
public class CheckinServiceImpl extends ServiceImpl<CheckinMapper, Checkin> implements ICheckinService {
  @Autowired
  private CheckinMapper checkinMapper;
  @Autowired
  private StudentMapper studentMapper;
  @Autowired
  private ScheduleMapper scheduleMapper;
  @Autowired
  private HscheckMapper hscheckMapper;
  @Autowired
  private WorkingMapper workingMapper;

  /**
   * 手动录入健康状态
   *
   * @param ids
   * @return
   */
  @Override
  public boolean inputCheckIn(Integer[] ids) {
    return checkinMapper.updateCheckInByIds(ids) > 0;
  }

  /**
   * 根据学生学号和健康码状态，对登记表跟核酸表选择填充
   * @param sno
   * @param inputJkmStatus
   * @return
   */
  @Override
  @Transactional
  public RespBean autoFillCheckIn(String sno, String inputJkmStatus) {

    /*更新学生的健康码*/
    String jkm_status = inputJkmStatus.equals("y") ? "绿码" : "非绿码";
    int i = studentMapper.update(new Student().setJkm_status(jkm_status),
            new LambdaUpdateWrapper<Student>().eq(Student::getSno, sno));
    if (i < 1) return RespBean.error("更新学生健康码状态失败,可能不存在该学号的学生,请重新输入!");

    /*    当值班人员手动录入健康码状态为 n 的情况处理流程    */
    if (inputJkmStatus.equals("n")) {
      List<Hscheck> hscheckList = hscheckMapper.selectList(new LambdaQueryWrapper<Hscheck>().eq(Hscheck::getSno,
              sno).orderByDesc(Hscheck::getCreatetime));
      if (hscheckList.size() != 0 && StrUtil.isEmpty(hscheckList.get(0).getHsResult())) {
        return RespBean.success("请勿频繁操作!请通知学生前往NA检测区做核酸");
      }
      Hscheck hscheck = new Hscheck().setCreatetime(LocalDateTime.now()).setSno(sno);
      if (hscheckMapper.insert(hscheck) < 1) return RespBean.error("新增核酸记录失败!");
      return RespBean.success("操作成功!请通知学生前往NA检测区做核酸");
    }


    /*    当值班人员手动录入健康码状态为 y 的情况处理流程    */

    //获取当前值班人员的账号
    String wno = AdminUtil.getCurrentAdmin().getUsername();
    //获取待入校的学生信息
    Student student = studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getSno, sno));

    LocalDateTime now = LocalDateTime.now();
    // 获取当日为星期几
    String weekOfDate = getWeekOfDate(new Date());
    // 获取当日所在周的星期一是几号
    String weekDate = getWeekDate();

    //获取当前值班人员的值班记录
   /* Schedule schedule =
            scheduleMapper.selectOne(new LambdaQueryWrapper<Schedule>().eq(Schedule::getWno, wno).le(Schedule::getBeginTime, now).ge(Schedule::getEndTime, now));*/
    Working working = workingMapper.selectOne(new QueryWrapper<Working>().eq("wno", wno).eq(weekOfDate, "上班").eq("sortDays", weekDate));
    if (working==null)
      return RespBean.error("当前操作员不在上班时间,无法进行录入");
    Checkin checkin = new Checkin().setSno(sno)
            .setSname(student.getSname()).setAddress(working.getAddress()).setWno(wno).setCreatetime(now).setJkm_status("y");
    //新增一条入校待录入记录
    if (checkinMapper.insert(checkin) > 0) return RespBean.success("");
    return RespBean.error("手动录入失败!");
  }

  /**
   * 分页获取所有记录（包含部分字段查询）
   * @param currentPage
   * @param size
   * @param checkin
   * @param beginDateScope
   * @return
   */
  @Override
  public RespPageBean getAllRecords(Integer currentPage, Integer size, Checkin checkin, LocalDate[] beginDateScope) {
    Page<Checkin> page = new Page<>(currentPage,size);
    IPage<Checkin> checkinIPage =checkinMapper.getAllRecords(page,checkin,beginDateScope);
    return new RespPageBean(checkinIPage.getTotal(),checkinIPage.getRecords());

  }

  /**
   * 获取指定日期是星期几<br>
   *
   * @param date
   * @return 指定日期是星期几
   */
  public static String getWeekOfDate(Date date) {
    String[] weekDays = { "sundayStatus", "mondayStatus", "tuesdayStatus", "wednesdayStatus", "thursdayStatus", "fridayStatus", "saturdayStatus" };
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
    if (w < 0)
      w = 0;
    return weekDays[w];
  }

  /**
   * 获取当前时间所在周的周一和周日的日期时间
   * @return
   */
  public static String getWeekDate() {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    Calendar cal = Calendar.getInstance();
    // 设置一个星期的第一天，按中国的习惯一个星期的第一天是星期一
    cal.setFirstDayOfWeek(Calendar.MONDAY);
    // 获得当前日期是一个星期的第几天
    int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
    if(dayWeek==1){
      dayWeek = 8;
    }

    cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);// 根据日历的规则，给当前日期减去星期几与一个星期第一天的差值
    Date mondayDate = cal.getTime();
    String weekBegin = sdf.format(mondayDate);

   /* cal.add(Calendar.DATE, 4 +cal.getFirstDayOfWeek());
    Date sundayDate = cal.getTime();
    String weekEnd = sdf.format(sundayDate);*/

    return weekBegin;
  }

}
